package org.example.util;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

/**
 * 已弃用
 */
@Slf4j
public class DecodeUtil {
    private String code;

    /**
     * 预处理，将编码转换为8bit一组的16进制字符串数组
     * @param hexString
     * @return
     */
    private static String[] preprocess(String hexString){
        char first=hexString.charAt(0);
        if(first=='N'){
            hexString=hexString.substring(1,hexString.length());
        }
        if (hexString == null || hexString.equals("")) {
            return null;
        }

        hexString = hexString.trim().replaceAll("\\s*", ""); // 去除字符串中的空格
        hexString=hexString.replaceAll("N","");
        hexString=hexString.toUpperCase();// 大写
//        System.out.println(hexString);
        String[] code=new String[hexString.length()/2];
        int i=0;

        try{
            while(true){
                code[i]=hexString.substring(0,2);//取前两个字符
//            System.out.println("code"+i+" "+code[i]);
                i++;
                hexString=hexString.substring(2,hexString.length());
                if(hexString == null || hexString.equals("")){
                    break;
                }
            }
        }
        catch (StringIndexOutOfBoundsException e){
            log.error("StringIndexOutOfException:",hexString,e);
            return null;
        }
//        for(String s:code){
//            System.out.print(s);
//        }
//        System.out.println();
        return code;
    }

    /**
     * 0x02 概要信息
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_02(String hexString){
        Map<String ,String> data= new HashMap<>();

        hexString="AABB2002"+hexString;     // 将去掉前缀的编码加上原来的前缀，这样后面就不用挨着改下标了
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        //code[3] 数据应答码---去掉
        if(Integer.parseInt(code[3])!=2){
            log.warn("Function code is not 0x02!");
            return null;
        }

        //code[20]上位机解析精度0表示0.1；1表示0.01
        int precise=Integer.parseInt(code[20],16);
//        System.out.println("precise:"+precise);

        //code[4] code[5] 总电压rackTotalVoltage
        BigDecimal totalVol=new BigDecimal(Integer.parseInt(code[4]+code[5],16));
        if(precise==1){//精度0.01
            BigDecimal d=new BigDecimal(100);
            data.put("rackTotalVoltage",totalVol.divide(d).toString());
        }
        else {//默认精度0.1
            BigDecimal d=new BigDecimal(10);
            data.put("rackTotalVoltage",totalVol.divide(d).toString());
        }

        //code[6] code[7] 总电流rackTotalCurrent
        BigDecimal totalCur=new BigDecimal(Integer.parseInt(code[6]+code[7],16));
        if(precise==1){//精度0.01
            BigDecimal d=new BigDecimal(100);
            data.put("rackTotalCurrent",totalCur.divide(d).toString());
        }
        else {//默认精度0.1
            BigDecimal d=new BigDecimal(10);
            data.put("rackTotalCurrent",totalCur.divide(d).toString());
        }


        //code[8] SOC当前电量rackSOC
        BigDecimal soc=new BigDecimal(Integer.parseInt(code[8],16));
        BigDecimal onehundred=new BigDecimal(100);
        data.put("racketSOC",soc.toString());

        //code[9] code[10]单体最高电压maxCellVoltage
        data.put("maxCellVoltage",String.valueOf(Integer.parseInt(code[9]+code[10],16)));

        //code[11]单体最高电压位置maxCellVoltageCellid
        data.put("maxCellVoltageCellid",String.valueOf(Integer.parseInt(code[11],16)));

        //code[12] code[13]单体最低电压minCellVoltage
        data.put("minCellVoltage",String.valueOf(Integer.parseInt(code[12]+code[13],16)));

        //code[14]单体最低电压位置minCellVoltageCellid
        data.put("minCellVoltageCellid",String.valueOf(Integer.parseInt(code[14],16)));

        //code[15]单体最高温度maxTemp
        BigDecimal maxTemp=new BigDecimal(Integer.parseInt(code[15],16));
        data.put("maxTemp",maxTemp.toString());

        //code[16]单体最高温度位置maxTempCellid
        data.put("maxCellTempCellid",String.valueOf(Integer.parseInt(code[16],16)));

        //code[17]单体最低温度minTemp
        BigDecimal minTemp=new BigDecimal(Integer.parseInt(code[17],16));
        data.put("minTemp",minTemp.toString());

        //code[18]单体最低温度位置minTempCellid
        data.put("minCellTempCellid",String.valueOf(Integer.parseInt(code[18],16)));

        //code[19]SOH电池健康值racketSOH
        BigDecimal soh=new BigDecimal(Integer.parseInt(code[19],16));
        data.put("racketSOH",soh.toString());

        //code[21]累计放电容量的24bit-16bit
        //code[22]累计充电容量的24bit-16bit
        //code[23]报警级别 1表示一级报警 2表示二级报警
        data.put("alarmLevel",String.valueOf(Integer.parseInt(code[23],16)));
        //code[24] code[25]当前系统剩余容量，默认0.1
        //code[26] code[27]软件默认版本号
        data.put("bms",String.valueOf(Integer.parseInt(code[26]+code[27],16)));

        //code[30] code[31]累计放电容量electricDischargeSum
        BigDecimal electricDischargeSum=new BigDecimal(Integer.parseInt(code[30]+code[31],16));
        if(precise==1){//精度0.01
            BigDecimal d=new BigDecimal(100);
            data.put("electricDischargeSum",electricDischargeSum.divide(d).toString());
        }
        else {//默认精度0.1
            BigDecimal d=new BigDecimal(10);
            data.put("electricDischargeSum",electricDischargeSum.divide(d).toString());
        }

        //code[30] code[31]累计充电容量electricChargeSum
        BigDecimal electricChargeSum=new BigDecimal(Integer.parseInt(code[30]+code[31],16));
        if(precise==1){//精度0.01
            BigDecimal d=new BigDecimal(100);
            data.put("electricChargeSum",electricChargeSum.divide(d).toString());
        }
        else {//默认精度0.1
            BigDecimal d=new BigDecimal(10);
            data.put("electricChargeSum",electricChargeSum.divide(d).toString());
        }
        return data;

    }

    /**
     * 0x03 报警信息
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_03(String hexString){
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        //code[0]+code[1]二级报警低16bit
        String secondErrorLow=code[0]+code[1];
        //code[2]+code[3]一级报警低16bit
        String firstErrorLow=code[2]+code[3];
        // code[4]+code[5]二级报警高16bit
        String secondErrorHigh=code[4]+code[5];
        // code[6]+code[7]一级报警高16bit
        String firstErrorHigh=code[6]+code[7];
        data.put("firstError",firstErrorHigh+firstErrorLow);
        data.put("secondError",secondErrorHigh+secondErrorLow);
        return data;
    }

    /**
     * 0x04 外部状态检测和MOS状态
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_04(String hexString){
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        // code[1] bmsSwitch MOS状态
        data.put("bmsSwitch",code[1]);
        return data;
    }

    /**
     * 0x10 单体电压
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_10(String hexString){
        Map<String ,String> data= new HashMap<>();
        hexString="AABB2710"+hexString;     // 将去掉前缀的编码加上原来的前缀，这样后面就不用挨着改下标了
        System.out.println(hexString);
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        if(Integer.parseInt(code[3])!=10){
            log.warn("Function code is not 0x10!");
            return null;
        }
        // code[4] 串数, 第i个为code[4+i*2-1]+code[4+i*2], i=[1,num]
        int num=Integer.parseInt(code[4],16);
        data.put("volsNum",String.valueOf(num));
        System.out.println("num of Vol:"+num);
        double volSum=0;
        for(int i=1;i<=num;i++){
            data.put("v"+String.valueOf(i),String.valueOf(Integer.parseInt(code[4+i*2-1]+code[4+i*2],16)));
            volSum+=Integer.parseInt(code[4+i*2-1]+code[4+i*2],16);
        }
        double averageVolttage=0;
        if(num!=0){
            averageVolttage=volSum/num;
        }
        //单体平均电压
        data.put("rackAverageVoltage",String.format("%.2f",averageVolttage));
//        for(String key : data.keySet()){
//            String value = data.get(key);
//            System.out.println(key+":"+value);
//        }
//        System.out.println(volSum);
        return data;
    }

    /**
     * 0x30 电芯温度
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_30(String hexString){//----------------------------待完善
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        //code[1]电芯温度01
        data.put("cell01_temp",String.valueOf(Integer.parseInt(code[1],16)));
        //code[2]电芯温度02
        data.put("cell02_temp",String.valueOf(Integer.parseInt(code[2],16)));
        //code[7]或code[8]为环境温度
        data.put("env01_temp",String.valueOf(Integer.parseInt(code[7],16)));
        data.put("env02_temp",String.valueOf(Integer.parseInt(code[8],16)));
//        if(Integer.parseInt(code[0],16)==0){//10为0则看11
//            if(Integer.parseInt(code[1])==0){//11为0直接返回null
//                return null;
//            }
//            data.put("env_temp",String.valueOf(Integer.parseInt(code[1],16)));//11不为0返回11
//        }
//        else{//10不为0返回10
//            data.put("env_temp",String.valueOf(Integer.parseInt(code[0],16)));
//        }
        //code[9] MOS温度01-充电MOS温度
        data.put("MOS01_temp",String.valueOf(Integer.parseInt(code[9],16)));
        //code[10] MOS温度02-放电MOS温度
        data.put("MOS02_temp",String.valueOf(Integer.parseInt(code[10],16)));
        return data;
    }

    /**
     * 0x53 读取一级报警二级报警参数 参数ID:81 电池类型BatteryType
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_53(String hexString){
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        //code[1]为电池类型 code[0]为81
        data.put("batteryType",String.valueOf(Integer.parseInt(code[1],16)));
        return data;
    }

    /**
     * 0x62读取硬件版本
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_62(String hexString){
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        // code[0-5] batchNo
//        long pcbBatch=Long.parseLong(code[0]+code[1]+code[2]+code[3]+code[4]+code[5],16);
        String pcbBatch="";
        for(int i=0;i<=5;i++){
//            System.out.println(Integer.parseInt(code[i])+" "+(char)Integer.parseInt(code[i],16));
            pcbBatch+=Character.toString((char) Integer.parseInt(code[i],16));
        }
        data.put("bmsBatchNo",pcbBatch);
        return data;
    }

    /**
     * 0x71 读取循环次数
     * @param hexString
     * @return
     */
    public static Map<String,String> decode_71(String hexString){
        Map<String ,String> data= new HashMap<>();
        String[] code=preprocess(hexString);
        if(code==null){
            return null;
        }
        // code[0] code[1]循环次数
        int cycleNum=Integer.parseInt(code[1]+code[0],16);
        data.put("cycleNum",String.valueOf(cycleNum));
        return data;
    }
    //16进制字符串转2进制，按位存到int数组中
    public static int[] hexToBinary(String hexString, int numBits) {
        int[] binaryArray = new int[numBits];
        String binaryString = new BigInteger(hexString, 16).toString(2);
        int binaryStringLength = binaryString.length();
        int numLeadingZeros = numBits - binaryStringLength;
        for (int i = 0; i < numLeadingZeros; i++) {
            binaryArray[i] = 0;
        }
        for (int i = numLeadingZeros; i < numBits; i++) {
            binaryArray[i] = binaryString.charAt(i - numLeadingZeros) - '0';
        }
        return binaryArray;
    }
    public static int[] decimalToBinary(String decimalString, int numBits) {
        int[] binaryArray = new int[numBits];
        String binaryString = new BigInteger(decimalString, 10).toString(2);
        int binaryStringLength = binaryString.length();
        int numLeadingZeros = numBits - binaryStringLength;
        for (int i = 0; i < numLeadingZeros; i++) {
            binaryArray[i] = 0;
        }
        for (int i = numLeadingZeros; i < numBits; i++) {
            binaryArray[i] = binaryString.charAt(i - numLeadingZeros) - '0';
        }
        return binaryArray;
    }

    public static void main(String args[]){
        String code02="03147530000ce9120cab0d4104350300000000010002000b006c0002";
        String code03="0000010000000000";
        String code04="0003";
        String code62="333630323730";
        String code10="0f0c3e0c3b0c3b0c4a0c130c3c0c160c3c0c3d0c150c400c180c3f0c400c1d0000000000000000";
        String code71="N0000";
//        System.out.println("code10 len:"+code10.length());
//        Map<String ,String> map=DecodeUtil.decode_02(code02);
//        Map<String ,String> map=DecodeUtil.decode_03(code03);
//        Map<String ,String> map=DecodeUtil.decode_04(code04);
//        Map<String ,String> map=DecodeUtil.decode_10(code10);
//        Map<String ,String> map=DecodeUtil.decode_62(code62);
//        Map<String ,String> map=DecodeUtil.decode_71(code71);
//        if(map.get("123")==null){
//            System.out.println("123");
//        }
//        try{
//            for(String key : map.keySet()){
//                String value = map.get(key);
//                System.out.println(key+":"+value);
//            }
//        }
//        catch (NullPointerException e){
//            System.out.println("nothing!");
//        }
//        int[] bit=hexToBinary(map.get("bmsSwitch"),8);
//        for(int i=0;i<bit.length;i++){
//            System.out.print(bit[i]+" ");
//        }

    }
}
